unit MainFrm;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, 
  Graphics, Controls, Forms, Dialogs, StdCtrls, 
   ExtCtrls, Menus;

const
  SX_MYMESSAGE = WM_USER+1;   

  MessString = '%s message now in %s.';

type
  TMainForm = class(TForm)
    GroupBox1: TGroupBox;
    EatMsgGB: TGroupBox;

    AppMsgCB: TCheckBox;
    WndProcCB: TCheckBox;
    MessProcCB: TCheckBox;
    DefHandCB: TCheckBox;

    EatMsgCB: TCheckBox;

    OnMsgRB: TRadioButton;
    WndProcRB: TRadioButton;
    MsgProcRB: TRadioButton;
    DefHandlerRB: TRadioButton;

    SendMessButton: TButton;
    PostMessButton: TButton;

    procedure FormCreate(Sender: TObject);

    procedure EatMsgCBClick(Sender: TObject);

    procedure PostMessButtonClick(Sender: TObject);
    procedure SendMessButtonClick(Sender: TObject);
    procedure AppMsgCBClick(Sender: TObject);
  private
    procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
    {on bat thong iep  cap WndProc}
    procedure WndProc(var Msg: TMessage); override;
    {on bat bang phng thc thong iep}
    procedure SXMyMessage(var Msg: TMessage); 
                                                          message SX_MYMESSAGE;
    procedure DefaultHandler(var Msg); override;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

const

  SendPostStrings: array[0..1] of String = (
                                                        'Sent', 'Posted');

procedure TMainForm.FormCreate(Sender: TObject);
begin

  Application.OnMessage := OnAppMessage;
 
  AppMsgCB.Tag := Longint(OnMsgRB);
  WndProcCB.Tag := Longint(WndProcRB);
  MessProcCB.Tag := Longint(MsgProcRB);
  DefHandCB.Tag := Longint(DefHandlerRB);

  OnMsgRB.Tag := Longint(AppMsgCB);
  WndProcRB.Tag := Longint(WndProcCB);
  MsgProcRB.Tag := Longint(MessProcCB);
  DefHandlerRB.Tag := Longint(DefHandCB);
end;

procedure TMainForm.OnAppMessage(var Msg: TMsg; 
                                                                  var Handled: Boolean);
begin
  if Msg.Message = SX_MYMESSAGE then
  begin
    if AppMsgCB.Checked then
    begin
      ShowMessage(Format(MessString, 
                             [SendPostStrings[Msg.WParam],
                              'Application.OnMessage']));
      Handled := OnMsgRB.Checked;
    end;
  end;
end;


procedure TMainForm.WndProc(var Msg: TMessage);
var
  CallInherited: Boolean;
begin
  CallInherited := True;          

  if Msg.Msg = SX_MYMESSAGE then   
  begin
    if WndProcCB.Checked then          begin
       ShowMessage(Format(MessString, 
                              [SendPostStrings[Msg.WParam], 
                             'WndProc']));
      CallInherited := not WndProcRB.Checked;
    end;
  end;

  if CallInherited then inherited WndProc(Msg);
end;


procedure TMainForm.SXMyMessage(var Msg: TMessage);
var
  CallInherited: Boolean;
begin
  CallInherited := True;           

 if MessProcCB.Checked then       
  begin
    ShowMessage(Format(MessString, 
                            [SendPostStrings[Msg.WParam],
                           'Message Procedure']));

     CallInherited := not MsgProcRB.Checked;
  end;
 
 if CallInherited then Inherited;
end;


procedure TMainForm.DefaultHandler(var Msg);
var
  CallInherited: Boolean;
begin
  CallInherited := True;       

  if TMessage(Msg).Msg = SX_MYMESSAGE then 
  begin
    if DefHandCB.Checked then      
    begin
      ShowMessage(Format(MessString, 
                            [SendPostStrings[TMessage(Msg).WParam],
                           'DefaultHandler']));
      CallInherited := not DefHandlerRB.Checked;
    end;
  end;
  if CallInherited then inherited DefaultHandler(Msg);
end;

procedure TMainForm.PostMessButtonClick(Sender:
                                                                                 TObject);
begin
  PostMessage(Handle, SX_MYMESSAGE, 1, 0);
end;

procedure TMainForm.SendMessButtonClick(Sender: 
                                                                                 TObject);
begin
  SendMessage(Handle, SX_MYMESSAGE, 0, 0); 
end;

procedure TMainForm.AppMsgCBClick(Sender: TObject);

begin
  if EatMsgCB.Checked then
  begin
    with TRadioButton((Sender as TCheckBox).Tag) do
    begin
      Enabled := TCheckbox(Sender).Checked;
      if not Enabled then Checked := False;
    end;
  end;
end;

procedure TMainForm.EatMsgCBClick(Sender: TObject);
var
  i: Integer;
  DoEnable, EatEnabled: Boolean;
begin
  EatEnabled := EatMsgCB.Checked;
  for i := 0 to EatMsgGB.ControlCount - 1 do
    with EatMsgGB.Controls[i] as TRadioButton do
    begin
      DoEnable := EatEnabled;
      if DoEnable then DoEnable := TCheckbox(Tag).Checked;
      if not DoEnable then Checked := False;
      Enabled := DoEnable;
    end;
end;

end.
